package P127_LockSynchronized;

import java.util.Calendar;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * @author xufy
 * @version 1.0
 * @description 显式锁Lock与内部锁synchronized
 **/
public class LockSynchronized {
    /**
     * 1）lock支持 读、写锁
     * 2）Lock是无阻塞锁，synchronized是阻塞锁
     * 3）Lock实现公平锁，synchronized非公平锁
     *   非公平锁，线程A持有锁，线程B、C等待中，若线程A释放锁，JVM从B、C中随机选择，而不是优先选择等待时间长的线程
     * 4）Lock是代码级的，synchronized是jvm级
     *    Lock: 灵活、功能强大
     *    synchronized：快捷、安全
     */
    //Lock是对象级的锁， synchronized是类基本的锁
    public static void main(String[] args) throws Exception {
        //共享lock，多线程互斥
//        runLockTask(TaskWithLock.class);
        runTasks(TaskWithLock.class);
        runTasks(TaskWithSync.class);
    }

    public static void runTasks(Class<? extends  Runnable> clz) throws Exception{
        ExecutorService es =Executors.newCachedThreadPool();
        System.out.println("*******开始执行"+clz.getSimpleName()+" 任务*****");
        for (int i = 0; i < 3; i++) {
            es.submit(clz.newInstance());
        }
        TimeUnit.SECONDS.sleep(10);
        System.out.println("-----"+clz.getSimpleName()+" 任务执行完毕-----\n");
        es.shutdown();
    }
    public static void runLockTask(Class<? extends  Runnable> clz) throws Exception{
        final Lock lock=new ReentrantLock();
        for (int i = 0; i < 3; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        lock.lock();
                        Thread.sleep(2000);
                        System.out.println(Thread.currentThread().getName());
                    }catch (InterruptedException e){
                        e.printStackTrace();

                    }finally {
                        lock.unlock();
                    }
                }
            }).start();
        }
    }
}


class TaskWithLock extends Task implements Runnable{
    //多线程类的私有属性是起不到资源互斥的
    private final Lock lock=new ReentrantLock();

    @Override
    public void run() {
        try {
            //加锁
            lock.lock();
            doSomething();
        }finally {
            //释放锁
            lock.unlock();
        }
    }
}
class TaskWithSync extends Task implements Runnable{

    @Override
    public void run() {
        synchronized ("A"){
            doSomething();
        }
    }
}

class Task{
    public void doSomething(){
        try{
            //等2s, 线程进入waiting状态
            Thread.sleep(2000);
        }catch(Exception e){
           //异常处理
        }
        StringBuffer sb=new StringBuffer();
        sb.append("线程名称："+Thread.currentThread().getName());
        sb.append("执行时间："+ Calendar.getInstance().get(13)+"s");
        System.out.println(sb);

    }
}
class Foo{
    private final ReentrantReadWriteLock rwl=new ReentrantReadWriteLock();
    private final Lock r=rwl.readLock();
    private final Lock w=rwl.writeLock();
    //多操作，可并发执行
    public void read(){
        try{
            r.lock();
            Thread.sleep(1000);
            System.out.println("read....");
        }catch (InterruptedException e){
            e.printStackTrace();
        }finally {
            r.unlock();
        }

    }
    public void write(Object _obj){
        try{
            w.lock();
            Thread.sleep(1000);
        }catch (InterruptedException e){
            e.printStackTrace();

        }finally {
            w.unlock();
        }
    }
}
